package dm.service;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Hashtable;

import org.apache.commons.httpclient.HttpClient;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;

import dm.bsi.Container;
import dm.bsi.Deployment;
import dm.bsi.Log;
import dm.bsi.Node;
import dm.bsi.Service;
import indi.zjh.dp.db.Session;

public class DpServiceManager implements Manager {
	
	private class PingException extends Exception
	{
		public PingException()
		{
			super();
		}
		
		public PingException(String message)
		{
			super(message);
		}
	}
	
	private class ContainerState
	{
		public static final int STATE_INIT = 0;
		public static final int STATE_PING = 1;
		
		public static final int MAX_TRY_COUNT = 3;
		
		public int state = STATE_INIT;
		public int tryCount = 0;
		private Socket socket = null;
		private PrintWriter out = null;
		private BufferedReader in = null;
		private String host;
		private int port;
		
		public void connect(String host, int port) throws UnknownHostException, IOException
		{
			
			
			this.host = host;
			this.port = port;
			
			
		}
		
		public void ping() throws PingException
		{
			try
			{
				
				if(this.out != null)
				{
					this.out.close();
				}
				if(this.in != null)
				{
					this.in.close();
				}
				
				if(this.socket != null)
				{
					this.socket.close();
				}
				
				this.socket = new Socket(this.host, this.port);
				
				this.out = new PrintWriter(this.socket.getOutputStream(), true);
				this.in = new BufferedReader(new InputStreamReader(this.socket.getInputStream()));
				
				
				this.out.print("GET /ping HTTP/1.1\r\n");
				this.out.print("User-Agent: dm\r\n");
				this.out.print("Host: "+this.host+":"+this.port+"\r\n");
				this.out.print("Connection: Keep-Alive\r\n");
				this.out.print("Keep-alive: 300\r\n");
				this.out.print("Accept: */*\r\n\r\n");
				this.out.flush();
	
				StringBuffer response = new StringBuffer();
				String line = null;
				while((line = this.in.readLine()) != null)
				{
					response.append(line);
				}

				if(!response.toString().contains("pong"))
				{

					throw new Exception("ping异常");
				}
				this.tryCount = 0;
				
				
			}
			catch(Exception e)
			{
				throw new PingException(e.getMessage());
			}
		}
	}
	
	private static Hashtable<String, ContainerState> containers = new Hashtable<String, ContainerState>();

	@Override
	public void process(Session session, Deployment deployment, Service service) throws Exception {
		// TODO Auto-generated method stub

	}

	@Override
	public void ping(Session session, Deployment deployment, Container container) throws Exception {
		// TODO Auto-generated method stub
		
		// 容器未被添加进管理池
		if(!containers.containsKey(container.getOid()))
		{
			ContainerState cState = new ContainerState();
			containers.put(container.getOid(), cState);
		}

		ContainerState thisState = containers.get(container.getOid());
		Node node = container.getNode(session);
		
		try
		{
			switch (thisState.state) {
			case ContainerState.STATE_INIT:
				thisState.state = ContainerState.STATE_PING;
				break;
			
			case ContainerState.STATE_PING:
				thisState.connect(node.getIp(), container.getDockerPort());
				thisState.ping();
				thisState.state = ContainerState.STATE_PING;
				break;
				
			default:
				
				break;
			}
		}
		catch(PingException ee)
		{
			thisState.state = ContainerState.STATE_INIT;
			Log.failure(session, deployment, "容器"+container.getOid()+"连接异常,"+ee.getMessage());
			if(thisState.tryCount++ >= ContainerState.MAX_TRY_COUNT)
			{
				containers.remove(container.getOid());
				throw new Exception(ee.getMessage());
			}
		}
	}

}
